import asyncio
import importlib.util
import logging
from pathlib import Path
from modules.others.base import module_regist

COMMAND_MAP = {}  # 精确
PREFIX_MAP = {}  # 前缀
PLUGINS_LOADED = False  # 已加载


def register_command(*names, match="exact"):
    """
    注册命令：
      @register_command("/reload")
      @register_command("找回卡号", match="startswith")
    """

    def decorator(func):
        if match == "startswith":
            for name in names:
                PREFIX_MAP[name] = func
        else:
            for name in names:
                COMMAND_MAP[name] = func
        return func

    return decorator


async def load_plugins(client,module_reload = False):
    """自动加载 ./plugins/ 目录下的所有模块"""
    global PLUGINS_LOADED
    content = ""
    if module_reload:
        module_reload_result = await module_regist(0, client.cmd_handler, client.lock, client.reply)
        content = "".join(module_reload_result).replace(".py", "")
    if PLUGINS_LOADED:
        return 0,content
    
    plugins_dir = Path("./plugins/")
    plugin_count = 0

    if not plugins_dir.exists():
        logging.warning(f"[Plugins] 目录不存在: {plugins_dir}")
        PLUGINS_LOADED = True
        return 0,content

    # 将 plugins 目录添加到 Python 路径
    import sys
    plugins_path = str(plugins_dir.parent.absolute())
    if plugins_path not in sys.path:
        sys.path.insert(0, plugins_path)

    # 加载根目录下的插件
    for py_file in plugins_dir.glob("*.py"):
        if py_file.stem == "__init__" or py_file.stem.startswith("_"):
            continue
            
        try:
            module_name = f"..plugins.{py_file.stem}"
            spec = importlib.util.spec_from_file_location(module_name, py_file)
            module = importlib.util.module_from_spec(spec)
            
            # 设置 __package__ 属性以便相对导入工作
            module.__package__ = f"plugins"
            
            spec.loader.exec_module(module)
            
            logging.info(f"[Plugins] 成功加载根目录插件: {py_file.stem}")
            plugin_count += 1
            
        except Exception as e:
            logging.error(f"[Plugins] 加载根目录模块失败 {py_file}: {e}")

    # 遍历所有子目录
    for module_dir in plugins_dir.iterdir():
        if module_dir.is_dir():
            for py_file in module_dir.glob("*.py"):
                try:
                    if py_file.stem == "__init__":
                        continue

                    module_name = f"plugins.{module_dir.name}.{py_file.stem}"
                    if module_name in sys.modules:
                        del sys.modules[module_name]  # 删除缓存

                    spec = importlib.util.spec_from_file_location(module_name, py_file)
                    module = importlib.util.module_from_spec(spec)
                    module.__package__ = f"plugins.{module_dir.name}"
                    spec.loader.exec_module(module)
                    plugin_count += 1
                except Exception as e:
                    logging.error(f"[Plugins] 加载模块失败 {py_file}: {e}")
    
    PLUGINS_LOADED = True
    logging.info(f"[Plugins] 加载完成，共 {plugin_count} 个插件")
    return plugin_count,content

async def handle_plugins_commands(client):
    """
    新版模块入口，旧的是./modules/*.py
    """
    await load_plugins(client)

    msg = client.msg.strip()
    if not msg:
        return False

    cmd = msg.split()[0]
    handler = COMMAND_MAP.get(cmd)

    # 前缀匹配
    if handler is None:
        for prefix, func in PREFIX_MAP.items():
            if msg.startswith(prefix):
                handler = func
                break

    if handler:
        try:
            async with asyncio.timeout(30):
                return await handler(client)
        except Exception as e:
            logging.error(f"[PluginsCmdError] {msg} -> {e}")
            return True

    return False


@register_command("reload")
async def plugins_reload_command(client):
    global PLUGINS_LOADED, COMMAND_MAP, PREFIX_MAP

    # 保存 reload 命令自身
    reload_cmd = COMMAND_MAP.get("reload")

    # 清空旧命令
    COMMAND_MAP.clear()
    PREFIX_MAP.clear()

    # 重新注册 reload 自身
    COMMAND_MAP["reload"] = reload_cmd

    PLUGINS_LOADED = False
    plugin_count, content = await load_plugins(client, module_reload=True) or 0
    if plugin_count > 1:
        content += f" plugin：{plugin_count}"
    await client.reply(content=f"done\n{content}")
    return True


@register_command("群号")
async def group_id_command(client):
    await client.reply(content=client.groupID)
    return True


@register_command("/help")
async def help_command(client):
    lines = []

    # 按 desc 首字母排序
    sorted_items = sorted(
        client.cmd_handler.help_map.items(), key=lambda x: x[1].lower()
    )

    for i, (kw, desc) in enumerate(sorted_items, start=1):
        lines.append(f"{i}. {desc}")  # 加序号

    content = "扫码查看APbot主鸡"
    # ，可使用触发词+帮助查看详细，当前已加载模块：\n" + "\n".join(lines) 用不到 注释了
    await client.reply(content=content,image = "./resource/apbot_main.png")
    return True
